/**
 * @class Aurora.Tab
 * @extends Aurora.Component
 * <p>Tab组件.
 * @author njq.niu@hand-china.com
 * @constructor
 * @param {Object} config 配置对象. 
 */
$S.Tab = Ext.extend($S.ViewComponent,{
    sd:'scroll-disabled',
    tslo:'tab-scroll-left-over',
    tsro:'tab-scroll-right-over',
    tsl:'tab-scroll-left',
    tsr:'tab-scroll-right',
    tc:'tab-close',
    tbo:'tab-btn-over',
    tbd:'tab-btn-down',
    ts:'tab-scroll',
    scrollWidth:36,
	constructor: function(config){
        this.intervalIds=[];
		$S.Tab.superclass.constructor.call(this,config);
	},
	initComponent:function(config){
		$S.Tab.superclass.initComponent.call(this, config);
		this.scriptwidth = config.scriptwidth||70;
		this.scripts = this.wrap.child('div[stype=tab.strips]'); 
		this.body = this.wrap.child('div.s_tab_body');
		this.scrollLeft = this.wrap.child('div[stype=scroll-left]');
		this.scrollRight = this.wrap.child('div[stype=scroll-right]');
		this.script = this.scripts.parent();
		this.selectTab(config.selected||0)
	},
	processListener: function(ou){
    	$S.Tab.superclass.processListener.call(this,ou);
    	this.script.parent()[ou]('mousedown',this.onMouseDown, this);
    	this.script.parent()[ou]('mouseup',this.onMouseUp, this);
    	this.script.parent()[ou]('mouseover',this.onMouseOver, this);
    	this.script.parent()[ou]('mouseout',this.onMouseOut, this);
    	this.script[ou]('click',this.onClick, this);
    	this.script[ou]('mousewheel',this.onMouseWheel, this);
    },
	initEvents:function(){
		$S.Tab.superclass.initEvents.call(this);   
		this.addEvents(
		/**
         * @event select
         * 选择事件.
         * @param {Aurora.Tab} tab Tab对象.
         * @param {Number} index 序号.
         */
		'select',
        /**
         * @event beforeopen
         * 选择事件.
         * @param {Aurora.Tab} tab Tab对象.
         * @param {Number} index 序号. 
         */
		'beforeopen'
		);
		
	},
    /**
     * 根据id获取item 
     * @param {String} id
     * @return {Object}
     */
    getItemById : function(id){
        for(var i = 0;i<this.items.length;i++){
            var item = this.items[i];
            if(item.id==id){
                return item;
            }
        }
    },
	/**
	 * 选中某个Tab页
	 * @param {Number} index TabItem序号
	 */
	selectTab:function(index,callback){
		var tab=this.getTab(index);
		if(!tab)return;
        if(tab.strip.hasClass(this.sd)){
            this.selectTab(tab.index+1);
            return;
        }
		var activeStrip = tab.strip,activeBody = tab.body;
		index=tab.index;
		if(activeStrip){
			if(this.activeTab)this.activeTab.replaceClass('active','unactive');
			this.activeTab = activeStrip;
			activeStrip.replaceClass('unactive','active');
			var l=activeStrip.dom.offsetLeft,w=activeStrip.getWidth(),
				sl=this.script.getScroll().left,sw=this.script.getWidth(),hw=this.scripts.getWidth();
				tr=l+w-sl-sw,tl=sl-l;
			if(tr>0){
				this.scrollRight.removeClass(this.sd);
				this.scrollLeft.removeClass(this.sd);
				this.script.scrollTo('left',sl+tr);
			}else if(tl>0){
				this.scrollLeft.removeClass(this.sd);
				this.script.scrollTo('left',sl-tl);
				this.scrollRight.removeClass(this.sd);
			}
			if(sw+this.script.getScroll().left>=hw){
				this.script.scrollTo('left',hw-sw);
				this.scrollRight.addClass(this.sd);                
			}else if(index==0){
				this.script.scrollTo('left',0);
				this.scrollLeft.addClass(this.sd);
			}
		}
		if(activeBody){
			if(this.activeBody){
				this.activeBody.setLeft('-10000px');
				this.activeBody.setTop('-10000px');
			}
			this.activeBody = activeBody;
			activeBody.setLeft('0px');
			activeBody.setTop('0px');
		}
		if(this.items[index].ref && activeBody.loaded!= true){
			this.load(this.items[index].ref,activeBody,index,this.items[index].para,callback);
			activeBody.loaded = true;
		}else{
            if(callback) callback.call(this);
            this.fireEvent('select', this, index)
		}
	},
	stripTpl:['<div class="strip unactive"  unselectable="on" onselectstart="return false;">'
				,'<div class="strip-left"></div>',
				'<div style="width:{stripwidth}px;" class="strip-center"><div class="tab-close"></div>{prompt}</div>',
				'<div class="strip-right"></div>',
			'</div>'],
	bodyTpl:'<div style="width:{bodywidth}px;height:{bodyheight}px;left:-10000px;top:-10000px;" class="tab"></div>',
	/**
	 * 打开一个指定引用地址的Tab页，如果该指定的引用地址的页面已经被打开，则选中该Tab页
	 * @param {String} ref Tab页面的引用地址
	 * @param {String} title Tab的标题
	 */
	openTab : function(opt){
        var id = opt.id
        var ref = opt.ref;
        var prompt = opt.title;
		var i=0;
		for(;i<this.items.length;i++){
            var item = this.items[i];
			if(item.ref&&item.id==id){
				this.selectTab(i,opt.callback);
                return;
			}
		}
		if(this.fireEvent('beforeopen',this,i)){
			this.items.push({ref:ref,id:id});
			var stripwidth= $S.TextMetrics.measure(prompt).width + 35;
			stripwidth=stripwidth<this.scriptwidth?this.scriptwidth:stripwidth;
			var width=this.scripts.getWidth()+stripwidth+6;
			this.scripts.setWidth(width);
			if(this.scrollStatus!= true && width>this.width){                
                this.scrollStatus = true;
                this.script.setWidth(this.width-this.scrollWidth);
				this.scrollLeft.setStyle({'display':'block'});
				this.scrollRight.setStyle({'display':'block'});
			}
			new Ext.Template(this.stripTpl).append(this.scripts.dom,{'prompt':prompt,'stripwidth':stripwidth});//,'stripwidth2':stripwidth+6
			new Ext.Template(this.bodyTpl).append(this.body.dom,{'bodywidth':this.body.getWidth()-Ext.fly(this.body).getBorderWidth('lr'),'bodyheight':this.body.getHeight()-Ext.fly(this.body).getBorderWidth('tb')});
			this.selectTab(i,opt.callback);
		}
	},
	/**
	 * 关闭某个Tab页
	 * @param {Integer} index TabItem序号
	 */
	closeTab : function(o, checkDirty){
        
		var tab=this.getTab(o);
        
		if(!tab)return;
		var strip=tab.strip,body=tab.body,index=tab.index,cmps=body.cmps;
        var item = this.items[index];
        if(item.closeable == false) {
            $S.showWarningMessage('提示','当前标签页正在执行后台程序,无法关闭!');
            return;
        }
		if(!strip.child('div.' + this.tc)){
			$S.showWarningMessage('警告','该标签页无法被关闭!')
			return;
		}
        if(checkDirty != false){
            var pass = true;
            for(var key in cmps){
                var cmp = cmps[key];
                if(cmp instanceof $S.DataSet && cmp.checkDirty && cmp.isDirty()){
                    pass = false;
                    break;
                }
            }
            if(!pass){
                var sf = this;
                var cw = $S.showConfirm('提示','当前标签页存在未保存的数据,是否关闭?', function(){
                    sf.closeTab(o, false); 
                    cw.close();
                })
                return;
            }
        }
        
        
        if(this.activeBody == tab.body){
            this.activeBody=null;
            this.activeTab=null;
        }
		this.items.splice(index,1);
		var width=this.scripts.getWidth()-strip.getWidth();
		this.scripts.setWidth(width);//TODO:测试IE8下，多个tab页下关闭性能
		if(this.scrollStatus!=false && width <= this.width){
            this.scrollStatus = false;
            this.script.setWidth(this.width);
			this.scrollLeft.setStyle({'display':'none'});
			this.scrollRight.setStyle({'display':'none'});
		}
        
        for(var key in cmps){
            var cmp = cmps[key];
            if(cmp.destroy){
                try{
                    cmp.destroy();
                }catch(e){
                    alert('销毁标签页出错: ' + e)
                }
            }
        }
		strip.remove();
		body.remove();
		
		delete body.loaded;
//		setTimeout(function(){
//        	for(var key in cmps){
//        		var cmp = cmps[key];
//        		if(cmp.destroy){
//        			try{
//        				cmp.destroy();
//        			}catch(e){
//        				alert('销毁标签页出错: ' + e)
//        			}
//        		}
//        	}
//        },10)
        var i = index<(this.items.length-1) ? index : (this.items.length-1)
		this.selectTab(i);
	},
    destroy : function(){
        var bodys = this.body.dom.children;
        for(var i=0;i<bodys.length;i++){
            var body = Ext.get(bodys[i]),
            cmps=body.cmps;
            if(cmps){
                for(var key in cmps){
                    var cmp = cmps[key];
                    if(cmp.destroy){
                        try{
                            cmp.destroy();
                        }catch(e){
                            alert('销毁出错: ' + e)
                        }
                    }
                }
            }
        }
        $S.Tab.superclass.destroy.call(this); 
    },
    /**
     * 将某个Tab页设为不可用。当TabItem有且仅有1个时，该方法无效果。
     * @param {Integer} index TabItem序号。当index<0时，TabItem序号等于TabItem的个数加上index。
     */
    setDisabled : function(index){
        var tab = this.getTab(index);
        if(!tab)return;
        if(this.items.length > 1){
            if(this.activeTab==tab.strip){
                this.selectTab(tab.index+(this.getTab(tab.index+1)?1:-1))
            }
            tab.strip.addClass(this.sd);
        }
    },
    /**
     * 将某个Tab页设为可用
     * @param {Integer} index TabItem序号。当index<0时，TabItem序号等于TabItem的个数加上index。
     */
    setEnabled : function(index){
        var tab = this.getTab(index);
        if(!tab)return;
        tab.strip.removeClass(this.sd);
    },
	getTab : function(o){
		var bodys = this.body.dom.children,
        strips = this.scripts.dom.children,
        strip,body;
		if(Ext.isNumber(o)){
			if(o<0)o+=strips.length;
            o=Math.round(o);
            if(strips[o]){
                strip=Ext.get(strips[o]);
                body=Ext.get(bodys[o]);
            }
		}else if(Ext.isString(o)){
            var item = this.getItemById(o);
            var index = this.items.indexOf(item);
            return this.getTab(index);
        } else {
			o = Ext.get(o);
			for(var i=0,l= strips.length;i<l;i++){
				if(Ext.get(strips[i]) == o){
					strip=o;
					body=Ext.get(bodys[i]);
					o=i;
					break;
				}
			}
		}
		return strip?{'strip':strip,'body':body,'index':o}:null;
	},
	scrollTo : function(lr){
		if(lr=='left'){
			this.script.scrollTo('left',this.script.getScroll().left-this.scriptwidth);
			this.scrollRight.removeClass(this.sd);
			if(this.script.getScroll().left<=0){
				this.scrollLeft.addClass(this.sd);
				this.scrollLeft.replaceClass(this.tslo,this.tsl);
				this.stopScroll();
			}
		}else if(lr=='right'){
			this.script.scrollTo('left',this.script.getScroll().left+this.scriptwidth);
			this.scrollLeft.removeClass(this.sd);
			if(this.script.getScroll().left+this.script.getWidth()>=this.scripts.getWidth()){
				this.scrollRight.addClass(this.sd);
				this.scrollRight.replaceClass(this.tsro,this.tsr);
				this.stopScroll();
			}
		}
	},
	stopScroll : function(){
		if(this.scrollInterval){
			clearInterval(this.scrollInterval);
			delete this.scrollInterval;
		}
	},
	onClick : function(e){
		var el=Ext.get(e.target);
		if(el.hasClass(this.tc))this.closeTab(el.parent('.strip'));
	},
	onMouseWheel : function(e){
		var delta = e.getWheelDelta();
        if(delta > 0){
            this.scrollTo('left');
            e.stopEvent();
        }else{
            this.scrollTo('right');
            e.stopEvent();
        }
	},
	onMouseDown : function(e){
		var el=Ext.get(e.target),strip = el.parent(),sf=this;
        if(el.hasClass(sf.tc)){
            el.removeClass(sf.tbo);
            el.addClass(sf.tbd);
        }else if(el.hasClass(sf.ts) && !el.hasClass(sf.sd)){
            if(el.hasClass(sf.tslo))sf.scrollTo('left');
            else sf.scrollTo('right');
            sf.scrollInterval=setInterval(function(){
                if(el.hasClass(sf.ts)&&!el.hasClass(sf.sd)){
                    if(el.hasClass(sf.tslo))sf.scrollTo('left');
                    else sf.scrollTo('right');
                    if(el.hasClass(sf.sd))clearInterval(sf.scrollInterval);
                }
            },100);
        }else if(strip.hasClass('strip') && !strip.hasClass('active') && !strip.hasClass(sf.sd)){
            sf.selectTab(strip);
        }
	},
	onMouseUp : function(e){
		this.stopScroll();
	},
	onMouseOver : function(e){
        var el=Ext.get(e.target),strip = el.parent('.strip');
        if(el.hasClass(this.ts)&&!el.hasClass(this.sd)){
            if(el.hasClass(this.tsl))el.replaceClass(this.tsl,this.tslo);
            else if(el.hasClass(this.tsr))el.replaceClass(this.tsr,this.tsro);
        } else if(el.hasClass(this.tc)){
            el.addClass(this.tbo);
        }
        if(strip){
            var el = strip.child('div.'+this.tc);
            if(el){
                if(this.currentBtn)this.currentBtn.hide();
                this.currentBtn=el;
                el.show();
            }            
        }
    },
    onMouseOut : function(e){
        var el=Ext.get(e.target),strip = el.parent('.strip');
        if(el.hasClass(this.ts)&&!el.hasClass(this.sd)){
            this.stopScroll();
            if(el.hasClass(this.tslo))el.replaceClass(this.tslo,this.tsl);
            else if((el.hasClass(this.tsro)))el.replaceClass(this.tsro,this.tsr);
        }else if(el.hasClass(this.tc)){
            el.removeClass(this.tbo);
            el.removeClass(this.tbd);
        }
        if(strip){
            el = strip.child('div.'+this.tc);
            if(el){
                el.hide();
            }            
        }
    },
	showLoading : function(dom){
    	dom.update('正在加载...');
    	dom.setStyle('text-align','center');
    	dom.setStyle('line-height',5);
    },
    clearLoading : function(dom){
    	dom.update('');
    	dom.setStyle('text-align','');
    	dom.setStyle('line-height','');
    },
	load : function(url,dom,index,para,callback){
        var sf = this,body = Ext.get(dom);
        body.cmps={};
        sf.showLoading(body);
        //TODO:错误信息
        if(para) {
            url = url + '?' + Ext.urlEncode(para);
        }
        Ext.Ajax.request({
            url: url,
            method: 'POST',
            params:{SUK:$S.suk,_sph:$S.viewHeight,_spw:$S.viewWidth},
            success: function(response, options){
                var html = response.responseText;
                sf.clearLoading(body);
                body.update(html,true,function(){
                    if(callback) callback.call(this)
                    sf.fireEvent('select', sf, index)
                },body);
            }
        });
    },
    setWidth : function(w){
    	w = Math.max(w,2);
    	if(this.width==w)return;
    	$S.Tab.superclass.setWidth.call(this, w);
        this.body.setWidth(w);
        this.script.setWidth(w-38);
    	if(w-38<this.scripts.getWidth()){
			this.scrollLeft.setStyle({'display':'block'});
			this.scrollRight.setStyle({'display':'block'});
			var sl=this.script.getScroll().left,sw=this.script.getWidth(),hw=this.scripts.getWidth();
			if(sl<=0) {
                this.scrollLeft.addClass(this.sd);
            } else {
                this.scrollLeft.removeClass(this.sd);
            }
			if(sl+sw>=hw){
				(!this.scrollRight.hasClass(this.sd)) ? this.scrollRight.addClass(this.sd) : this.script.scrollTo('left',hw-sw);
			}else {
                this.scrollRight.removeClass(this.sd);
            }
    	}else{
			this.scrollLeft.setStyle({'display':'none'});
			this.scrollRight.setStyle({'display':'none'});
			this.script.scrollTo('left',0);
    	}
        var bodys = this.body.dom.children;
        for(var i=0;i<bodys.length;i++){
            var body = bodys[i];
            Ext.fly(body).setWidth(w);//-2
        }
    },
    setHeight : function(h){
    	h = Math.max(h,25);
    	if(this.height==h)return;
    	$S.Tab.superclass.setHeight.call(this, h);
        this.body.setHeight(h-(27-Ext.fly(this.body).getBorderWidth('tb')));
        var bodys = this.body.dom.children;
        for(var i=0;i<bodys.length;i++){
            var body = bodys[i];
            Ext.fly(body).setHeight(h-27);
        }
    }
});